//-----------------------------------------------------------------------
//  This file is based on Microsoft Robotics Developer Studio Code Samples.
// 
//  Portions Copyright (C) Microsoft Corporation.  All rights reserved.
//  Updated service created by Trevor Taylor.
//  This code released under the terms of the 
//  Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html)
//
//  $File: HiTechnicTouchMuxTypes.cs $ $Revision: 1 $
//-----------------------------------------------------------------------

using Microsoft.Dss.Core.Attributes;
using System;
using System.Collections.Generic;
//using brick = Microsoft.Robotics.Services.Sample.Lego.Nxt.Brick;
using contactsensor = Microsoft.Robotics.Services.ContactSensor.Proxy;
using System.ComponentModel;
using System.Xml.Serialization;
using Microsoft.Dss.ServiceModel.Dssp;
using Microsoft.Ccr.Core;
using W3C.Soap;
using dssphttp = Microsoft.Dss.Core.DsspHttp;
using nxtcmd = Microsoft.Robotics.Services.Sample.Lego.Nxt.Commands;
using Microsoft.Dss.Core.Utilities;
using Microsoft.Robotics.Services.Sample.Lego.Nxt.Common;


namespace Microsoft.Robotics.Services.Sample.HiTechnic.TouchMux
{
    /// <summary>
    /// HiTechnic Touch Mux Contract
    /// </summary>
    public sealed class Contract
    {
        /// The Unique Contract Identifier for the HiTechnic Touch Mux service
        [DataMember, Description("Identifies the Unique Contract Identifier for the HiTechnic Touch Mux service.")]
        public const String Identifier = "http://schemas.microsoft.com/robotics/2009/12/hitechnic/nxt/touchmux.html";

        /// <summary>
        /// The HiTechnic Touch Mux Device Type
        /// </summary>
        [DataMember, Description("Identifies the HiTechnic Touch Mux Device Type.")]
        public const string DeviceModel = "TouchMux";

        /// <summary>
        /// Default Polling Frequency (ms)
        /// </summary>
        [DataMember, Description("Specifies the default Polling Frequency (ms).")]
        public const int DefaultPollingFrequencyMs = 100;

    }

    /// <summary>
    /// HiTechnic Touch Mux State
    /// </summary>
    [DataContract, Description("Specifies the HiTechnic Touch Mux state.")]
    public class TouchMuxState 
    {
        /// <summary>
        /// Is the Sensor connected to a LEGO Brick?
        /// </summary>
        [DataMember(IsRequired = false), Description("Indicates a connection to the LEGO NXT Brick Service.")]
        [Browsable(false)]
        public bool Connected;

        /// <summary>
        /// The name of this Touch Sensor instance
        /// </summary>
        [DataMember, Description("Specifies a user friendly name for the HiTechnic Touch Mux.")]
        public string Name;

        /// <summary>
        /// LEGO NXT Sensor Port
        /// </summary>
        [DataMember, Description("Specifies the LEGO NXT Sensor Port.")]
        public NxtSensorPort SensorPort;

        /// <summary>
        /// Polling Frequency (ms)
        /// </summary>
        [DataMember, Description("Indicates the Polling Frequency in milliseconds (0 = default).")]
        public int PollingFrequencyMs;

        /// <summary>
        /// The current state of the All the Touch Sensors (0-15)
        /// </summary>
        [DataMember, Description("Indicates the current state of all the Touch Sensors on the Mux (0-15).")]
        [Browsable(false)]
        public byte AllTouchSensors;

        /// <summary>
        /// The current state of the Touch Sensor 1
        /// </summary>
        [DataMember, Description("Indicates the current state of the Touch Mux Sensor 1.")]
        [Browsable(false)]
        public bool TouchSensor1On;

        /// <summary>
        /// The current state of the Touch Sensor 2
        /// </summary>
        [DataMember, Description("Indicates the current state of the Touch Mux Sensor 2.")]
        [Browsable(false)]
        public bool TouchSensor2On;

        /// <summary>
        /// The current state of the Touch Sensor 3
        /// </summary>
        [DataMember, Description("Indicates the current state of the Touch Mux Sensor 3.")]
        [Browsable(false)]
        public bool TouchSensor3On;

        /// <summary>
        /// The current state of the Touch Sensor 4
        /// </summary>
        [DataMember, Description("Indicates the current state of the Touch Mux Sensor 4.")]
        [Browsable(false)]
        public bool TouchSensor4On;

        /// <summary>
        /// The time of the last sensor update
        /// </summary>
        [DataMember, Description("Indicates the time of the last sensor reading.")]
        [Browsable(false)]
        public DateTime TimeStamp;
    }

    /// <summary>
    /// Get the HiTechnic Touch Mux State
    /// </summary>
    [Description("Gets the current state of the HiTechnic Touch Mux.")]
    public class Get : Get<GetRequestType, PortSet<TouchMuxState, Fault>>
    {
    }

    /// <summary>
    /// Update the HiTechnic Touch Mux State
    /// </summary>
    [Description("Indicates an update to the HiTechnic Touch Mux State.")]
    public class TouchMuxUpdate : Update<TouchMuxState, PortSet<DefaultUpdateResponseType, Fault>>
    {
    }

    /// <summary>
    /// Configure Device Connection
    /// </summary>
    [DisplayName("ConnectionUpdate")]
    [Description("Connects the HiTechnic Touch Mux to be plugged into the NXT Brick.")]
    public class ConnectToBrick : Update<TouchMuxConfig, PortSet<DefaultUpdateResponseType, Fault>>
    {
        /// <summary>
        /// Configure Device Connection
        /// </summary>
        public ConnectToBrick()
        {
        }

        /// <summary>
        /// Configure Device Connection
        /// </summary>
        /// <param name="sensorPort"></param>
        public ConnectToBrick(NxtSensorPort sensorPort)
            : base(new TouchMuxConfig(sensorPort))
        {
        }

    }

    /// <summary>
    /// HiTechnic Touch Mux Configuration.
    /// </summary>
    [DataContract, Description("Specifies the HiTechnic Touch Mux Configuration.")]
    public class TouchMuxConfig
    {
        /// <summary>
        /// HiTechnic Touch Mux Configuration.
        /// </summary>
        public TouchMuxConfig() { }

        /// <summary>
        /// HiTechnic Touch Mux Configuration.
        /// </summary>
        /// <param name="sensorPort"></param>
        public TouchMuxConfig(NxtSensorPort sensorPort)
        {
            this.SensorPort = sensorPort;
        }

        /// <summary>
        /// The name of this Touch Mux instance
        /// </summary>
        [DataMember, Description("Specifies a user friendly name for the HiTechnic Touch Mux.")]
        public string Name;

        /// <summary>
        /// LEGO NXT Sensor Port
        /// </summary>
        [DataMember, Description("Specifies the LEGO NXT Sensor Port.")]
        [DataMemberConstructor]
        public NxtSensorPort SensorPort;

        /// <summary>
        /// Polling Freqency (ms)
        /// </summary>
        [DataMember, Description("Indicates the Polling Frequency in milliseconds (0 = default).")]
        public int PollingFrequencyMs;

    }

    /// <summary>
    /// HiTechnic Touch Mux Operations Port
    /// </summary>
    [ServicePort]
    public class TouchMuxOperations : PortSet
    {
        /// <summary>
        /// HiTechnic Touch Mux Operations Port
        /// </summary>
        public TouchMuxOperations()
            : base(
                typeof(DsspDefaultLookup),
                typeof(DsspDefaultDrop),
                typeof(ConnectToBrick),
                typeof(dssphttp.HttpGet),
                typeof(Get),
                typeof(TouchMuxUpdate),
                typeof(contactsensor.ReliableSubscribe),
                typeof(contactsensor.Subscribe)
            )
        { }

        /// <summary>
        /// Post Configure Sensor Connection with body and return the response port.
        /// </summary>
        public virtual PortSet<DefaultUpdateResponseType, Fault> ConnectToBrick(TouchMuxConfig body)
        {
            ConnectToBrick op = new ConnectToBrick();
            op.Body = body ?? new TouchMuxConfig();
            this.PostUnknownType(op);
            return op.ResponsePort;
        }

        /// <summary>
        /// Post Configure Sensor Connection with body and return the response port.
        /// </summary>
        public virtual PortSet<DefaultUpdateResponseType, Fault> ConnectToBrick(TouchMuxState state)
        {
            ConnectToBrick op = new ConnectToBrick();
            op.Body = new TouchMuxConfig(state.SensorPort);
            op.Body.Name = state.Name;
            op.Body.PollingFrequencyMs = state.PollingFrequencyMs;

            this.PostUnknownType(op);
            return op.ResponsePort;
        }

        /// <summary>
        /// Post Configure Sensor Connection with body and return the response port.
        /// </summary>
        /// <param name="sensorPort"></param>
        /// <returns></returns>
        public virtual PortSet<DefaultUpdateResponseType, Fault> ConnectToBrick(NxtSensorPort sensorPort)
        {
            ConnectToBrick op = new ConnectToBrick(sensorPort);
            this.PostUnknownType(op);
            return op.ResponsePort;
        }
    }

    /// <summary>
    /// HiTechnic Touch Mux Sensor Masks
    /// </summary>
    [DataContract, Description("Specifies the HiTechnic Touch Mux Sensor Masks.")]
    public enum TouchMuxSensorMasks
    {
        /// <summary>
        /// Sensor1
        /// </summary>
        Sensor1 = 1,
        /// <summary>
        /// Sensor2
        /// </summary>
        Sensor2 = 2,
        /// <summary>
        /// Sensor3
        /// </summary>
        Sensor3 = 4,
        /// <summary>
        /// Sensor4
        /// </summary>
        Sensor4 = 8
    }

}
